using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;


//你不需要知道这里面发生了什么。
//YOU DO NOT NEED HAVE TO KNOW WHAT IS HAPPEND HERE.
internal delegate IntPtr WndProcHandler(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

internal struct Win32
{
    internal static readonly IntPtr TRUE = new IntPtr(1);
    internal static readonly IntPtr FALSE = new IntPtr(0);

    internal static readonly IntPtr MESSAGE_HANDLED = new IntPtr(1);
    internal static readonly IntPtr MESSAGE_PROCESS = new IntPtr(0);
    internal const int CornerAreaSize = 4;

    internal static IntPtr MakeParam(IntPtr l, IntPtr h)
    {
        return (IntPtr)((l.ToInt32() & 0xffff) | (h.ToInt32() << 0x10));
    }

    internal static IntPtr MakeParam(int l, int h)
    {
        return (IntPtr)((l & 0xffff) | (h << 0x10));
    }


    internal static int SignedLOWORD(IntPtr ptr)
    {
        return (int)LOWORD(ptr);
    }

    internal static int SignedHIWORD(IntPtr ptr)
    {
        return (int)HIWORD(ptr);
    }

    internal static uint LOWORD(IntPtr ptr)
    {
        return (uint)(ptr.ToInt32() & 0xFFFF);
    }

    internal static uint HIWORD(IntPtr ptr)
    {
        if (((uint)ptr & 0x80000000) == 0x80000000)
        {
            return ((uint)ptr >> 16);
        }

        return ((uint)ptr >> 16) & 0xffff;
    }


    internal static int LOWORD(int dwValue)
    {
        return dwValue & 0xffff;
    }


    internal static int HIWORD(int dwValue)
    {
        return (dwValue >> 16) & 0xffff;
    }

    internal static POINT GetPostionFromPtr(IntPtr lparam)
    {
        var scaledX = SignedLOWORD(lparam);
        var scaledY = SignedHIWORD(lparam);

        var x = scaledX;
        var y = scaledY;

        return new POINT(x, y);
    }

    internal static HitTest GetSizeMode(POINT point, int width, int height)
    {
        HitTest mode = HitTest.HTCLIENT;

        int x = point.x, y = point.y;

        if (x < CornerAreaSize & y < CornerAreaSize)
        {
            mode = HitTest.HTTOPLEFT;
        }
        else if (x < CornerAreaSize & y + CornerAreaSize > height - CornerAreaSize)
        {
            mode = HitTest.HTBOTTOMLEFT;

        }
        else if (x + CornerAreaSize > width - CornerAreaSize & y + CornerAreaSize > height - CornerAreaSize)
        {
            mode = HitTest.HTBOTTOMRIGHT;

        }
        else if (x + CornerAreaSize > width - CornerAreaSize & y < CornerAreaSize)
        {
            mode = HitTest.HTTOPRIGHT;

        }
        else if (x < CornerAreaSize)
        {
            mode = HitTest.HTLEFT;

        }
        else if (x + CornerAreaSize > width - CornerAreaSize)
        {
            mode = HitTest.HTRIGHT;

        }
        else if (y < CornerAreaSize)
        {
            mode = HitTest.HTTOP;

        }
        else if (y + CornerAreaSize > height - CornerAreaSize)
        {
            mode = HitTest.HTBOTTOM;
        }

        return mode;
    }

}

public enum IDC_STANDARD_CURSORS
{
    IDC_ARROW = 32512,
    IDC_IBEAM = 32513,
    IDC_WAIT = 32514,
    IDC_CROSS = 32515,
    IDC_UPARROW = 32516,
    IDC_SIZE = 32640,
    IDC_ICON = 32641,
    IDC_SIZENWSE = 32642,
    IDC_SIZENESW = 32643,
    IDC_SIZEWE = 32644,
    IDC_SIZENS = 32645,
    IDC_SIZEALL = 32646,
    IDC_NO = 32648,
    IDC_HAND = 32649,
    IDC_APPSTARTING = 32650,
    IDC_HELP = 32651
}

/// <summary>
/// The services requested. This member can be a combination of the following values.
/// </summary>
[Flags]
public enum TMEFlags : uint
{
    /// <summary>
    /// The caller wants to cancel a prior tracking request. The caller should also specify the type of tracking that it wants to cancel. For example, to cancel hover tracking, the caller must pass the TME_CANCEL and TME_HOVER flags.
    /// </summary>
    TME_CANCEL = 0x80000000,
    /// <summary>
    /// The caller wants hover notification. Notification is delivered as a WM_MOUSEHOVER message.
    /// If the caller requests hover tracking while hover tracking is already active, the hover timer will be reset.
    /// This flag is ignored if the mouse pointer is not over the specified window or area.
    /// </summary>
    TME_HOVER = 0x00000001,
    /// <summary>
    /// The caller wants leave notification. Notification is delivered as a WM_MOUSELEAVE message. If the mouse is not over the specified window or area, a leave notification is generated immediately and no further tracking is performed.
    /// </summary>
    TME_LEAVE = 0x00000002,
    /// <summary>
    /// The caller wants hover and leave notification for the nonclient areas. Notification is delivered as WM_NCMOUSEHOVER and WM_NCMOUSELEAVE messages.
    /// </summary>
    TME_NONCLIENT = 0x00000010,
    /// <summary>
    /// The function fills in the structure instead of treating it as a tracking request. The structure is filled such that had that structure been passed to TrackMouseEvent, it would generate the current tracking. The only anomaly is that the hover time-out returned is always the actual time-out and not HOVER_DEFAULT, if HOVER_DEFAULT was specified during the original TrackMouseEvent request.
    /// </summary>
    TME_QUERY = 0x40000000,
}

[StructLayout(LayoutKind.Sequential)]
public struct TRACKMOUSEEVENTS
{
    public uint cbSize;
    public uint dwFlags;
    public IntPtr hWnd;
    public uint dwHoverTime;
}

public struct MARGINS                           // struct for box shadow
{
    public int leftWidth;
    public int rightWidth;
    public int topHeight;
    public int bottomHeight;
}
internal enum ABMsg : int
{
    ABM_NEW = 0,
    ABM_REMOVE,
    ABM_QUERYPOS,
    ABM_SETPOS,
    ABM_GETSTATE,
    ABM_GETTASKBARPOS,
    ABM_ACTIVATE,
    ABM_GETAUTOHIDEBAR,
    ABM_SETAUTOHIDEBAR,
    ABM_WINDOWPOSCHANGED,
    ABM_SETSTATE
}

public enum WindowActiveFlags : uint
{
    WA_INACTIVE = 0,
    WA_ACTIVE = 1,
    WA_CLICKACTIVE = 2
}

public enum ABEdge : int
{
    ABE_LEFT = 0,
    ABE_TOP,
    ABE_RIGHT,
    ABE_BOTTOM
}

[StructLayout(LayoutKind.Sequential)]
internal struct APPBARDATA
{
    public int cbSize;
    public IntPtr hWnd;
    public uint uCallbackMessage;
    public uint uEdge;
    public RECT rc;
    public IntPtr lParam;
}

public enum PenStyle : int
{
    PS_SOLID = 0, //The pen is solid.
    PS_DASH = 1, //The pen is dashed.
    PS_DOT = 2, //The pen is dotted.
    PS_DASHDOT = 3, //The pen has alternating dashes and dots.
    PS_DASHDOTDOT = 4, //The pen has alternating dashes and double dots.
    PS_NULL = 5, //The pen is invisible.
    PS_INSIDEFRAME = 6,// Normally when the edge is drawn, it’s centred on the outer edge meaning that half the width of the pen is drawn
                       // outside the shape’s edge, half is inside the shape’s edge. When PS_INSIDEFRAME is specified the edge is drawn 
                       //completely inside the outer edge of the shape.
    PS_USERSTYLE = 7,
    PS_ALTERNATE = 8,
    PS_STYLE_MASK = 0x0000000F,

    PS_ENDCAP_ROUND = 0x00000000,
    PS_ENDCAP_SQUARE = 0x00000100,
    PS_ENDCAP_FLAT = 0x00000200,
    PS_ENDCAP_MASK = 0x00000F00,

    PS_JOIN_ROUND = 0x00000000,
    PS_JOIN_BEVEL = 0x00001000,
    PS_JOIN_MITER = 0x00002000,
    PS_JOIN_MASK = 0x0000F000,

    PS_COSMETIC = 0x00000000,
    PS_GEOMETRIC = 0x00010000,
    PS_TYPE_MASK = 0x000F0000
};

public enum MonitorFromWindowFlags : uint
{
    MONITOR_DEFAULTTONULL = 0x0,
    MONITORINFOF_PRIMARY = 0x1,
    MONITOR_DEFAULTTONEAREST = 0x2,
    MONITOR_DEFAULTTOPRIMARY = 0x1
}


public enum SystemCommandFlags
{
    SC_SIZE = 0xF000,
    SC_MOVE = 0xF010,
    SC_MINIMIZE = 0xF020,
    SC_MAXIMIZE = 0xF030,
    SC_NEXTWINDOW = 0xF040,
    SC_PREVWINDOW = 0xF050,
    SC_CLOSE = 0xF060,
    SC_VSCROLL = 0xF070,
    SC_HSCROLL = 0xF080,
    SC_MOUSEMENU = 0xF090,
    SC_KEYMENU = 0xF100,
    SC_ARRANGE = 0xF110,
    SC_RESTORE = 0xF120,
    SC_TASKLIST = 0xF130,
    SC_SCREENSAVE = 0xF140,
    SC_HOTKEY = 0xF150,
    SC_DEFAULT = 0xF160,
    SC_MONITORPOWER = 0xF170,
    SC_CONTEXTHELP = 0xF180,
    SC_SEPARATOR = 0xF00F,
    SCF_ISSECURE = 0x00000001,
}

public enum MonitorDpiType : int
{
    MDT_EFFECTIVE_DPI = 0,
    MDT_ANGULAR_DPI = 1,
    MDT_RAW_DPI = 2,
    MDT_DEFAULT = MDT_EFFECTIVE_DPI
}

public enum DeviceScaleFactor
{
    SCALE_100_PERCENT = 100,
    SCALE_120_PERCENT = 120,
    SCALE_140_PERCENT = 140,
    SCALE_150_PERCENT = 150,
    SCALE_160_PERCENT = 160,
    SCALE_180_PERCENT = 180,
    SCALE_225_PERCENT = 225
}

public enum SystemMetricFlags : int
{
    /// <summary>
    /// The flags that specify how the system arranged minimized windows. For more information, see the Remarks section in this topic.
    /// </summary>
    SM_ARRANGE = 56,

    /// <summary>
    /// The value that specifies how the system is started: 
    /// 0 Normal boot
    /// 1 Fail-safe boot
    /// 2 Fail-safe with network boot
    /// A fail-safe boot (also called SafeBoot, Safe Mode, or Clean Boot) bypasses the user startup files.
    /// </summary>
    SM_CLEANBOOT = 67,

    /// <summary>
    /// The number of display monitors on a desktop. For more information, see the Remarks section in this topic.
    /// </summary>
    SM_CMONITORS = 80,

    /// <summary>
    /// The number of buttons on a mouse, or zero if no mouse is installed.
    /// </summary>
    SM_CMOUSEBUTTONS = 43,

    /// <summary>
    /// The width of a window border, in pixels. This is equivalent to the SM_CXEDGE value for windows with the 3-D look.
    /// </summary>
    SM_CXBORDER = 5,

    /// <summary>
    /// The width of a cursor, in pixels. The system cannot create cursors of other sizes.
    /// </summary>
    SM_CXCURSOR = 13,

    /// <summary>
    /// This value is the same as SM_CXFIXEDFRAME.
    /// </summary>
    SM_CXDLGFRAME = 7,

    /// <summary>
    /// The width of the rectangle around the location of a first click in a double-click sequence, in pixels. ,
    /// The second click must occur within the rectangle that is defined by SM_CXDOUBLECLK and SM_CYDOUBLECLK for the system
    /// to consider the two clicks a double-click. The two clicks must also occur within a specified time.
    /// To set the width of the double-click rectangle, call SystemParametersInfo with SPI_SETDOUBLECLKWIDTH.
    /// </summary>
    SM_CXDOUBLECLK = 36,

    /// <summary>
    /// The number of pixels on either side of a mouse-down point that the mouse pointer can move before a drag operation begins. 
    /// This allows the user to click and release the mouse button easily without unintentionally starting a drag operation. 
    /// If this value is negative, it is subtracted from the left of the mouse-down point and added to the right of it.
    /// </summary>
    SM_CXDRAG = 68,

    /// <summary>
    /// The width of a 3-D border, in pixels. This metric is the 3-D counterpart of SM_CXBORDER.
    /// </summary>
    SM_CXEDGE = 45,

    /// <summary>
    /// The thickness of the frame around the perimeter of a window that has a caption but is not sizable, in pixels.
    /// SM_CXFIXEDFRAME is the height of the horizontal border, and SM_CYFIXEDFRAME is the width of the vertical border.
    /// This value is the same as SM_CXDLGFRAME.
    /// </summary>
    SM_CXFIXEDFRAME = 7,

    /// <summary>
    /// The width of the left and right edges of the focus rectangle that the DrawFocusRectdraws. 
    /// This value is in pixels. 
    /// Windows 2000:  This value is not supported.
    /// </summary>
    SM_CXFOCUSBORDER = 83,

    /// <summary>
    /// This value is the same as SM_CXSIZEFRAME.
    /// </summary>
    SM_CXFRAME = 32,

    /// <summary>
    /// The width of the client area for a full-screen window on the primary display monitor, in pixels. 
    /// To get the coordinates of the portion of the screen that is not obscured by the system taskbar or by application desktop toolbars, 
    /// call the SystemParametersInfofunction with the SPI_GETWORKAREA value.
    /// </summary>
    SM_CXFULLSCREEN = 16,

    /// <summary>
    /// The width of the arrow bitmap on a horizontal scroll bar, in pixels.
    /// </summary>
    SM_CXHSCROLL = 21,

    /// <summary>
    /// The width of the thumb box in a horizontal scroll bar, in pixels.
    /// </summary>
    SM_CXHTHUMB = 10,

    /// <summary>
    /// The default width of an icon, in pixels. The LoadIcon function can load only icons with the dimensions 
    /// that SM_CXICON and SM_CYICON specifies.
    /// </summary>
    SM_CXICON = 11,

    /// <summary>
    /// The width of a grid cell for items in large icon view, in pixels. Each item fits into a rectangle of size 
    /// SM_CXICONSPACING by SM_CYICONSPACING when arranged. This value is always greater than or equal to SM_CXICON.
    /// </summary>
    SM_CXICONSPACING = 38,

    /// <summary>
    /// The default width, in pixels, of a maximized top-level window on the primary display monitor.
    /// </summary>
    SM_CXMAXIMIZED = 61,

    /// <summary>
    /// The default maximum width of a window that has a caption and sizing borders, in pixels. 
    /// This metric refers to the entire desktop. The user cannot drag the window frame to a size larger than these dimensions. 
    /// A window can override this value by processing the WM_GETMINMAXINFO message.
    /// </summary>
    SM_CXMAXTRACK = 59,

    /// <summary>
    /// The width of the default menu check-mark bitmap, in pixels.
    /// </summary>
    SM_CXMENUCHECK = 71,

    /// <summary>
    /// The width of menu bar buttons, such as the child window close button that is used in the multiple document interface, in pixels.
    /// </summary>
    SM_CXMENUSIZE = 54,

    /// <summary>
    /// The minimum width of a window, in pixels.
    /// </summary>
    SM_CXMIN = 28,

    /// <summary>
    /// The width of a minimized window, in pixels.
    /// </summary>
    SM_CXMINIMIZED = 57,

    /// <summary>
    /// The width of a grid cell for a minimized window, in pixels. Each minimized window fits into a rectangle this size when arranged. 
    /// This value is always greater than or equal to SM_CXMINIMIZED.
    /// </summary>
    SM_CXMINSPACING = 47,

    /// <summary>
    /// The minimum tracking width of a window, in pixels. The user cannot drag the window frame to a size smaller than these dimensions. 
    /// A window can override this value by processing the WM_GETMINMAXINFO message.
    /// </summary>
    SM_CXMINTRACK = 34,

    /// <summary>
    /// The amount of border padding for captioned windows, in pixels. Windows XP/2000:  This value is not supported.
    /// </summary>
    SM_CXPADDEDBORDER = 92,

    /// <summary>
    /// The width of the screen of the primary display monitor, in pixels. This is the same value obtained by calling 
    /// GetDeviceCaps as follows: GetDeviceCaps( hdcPrimaryMonitor, HORZRES).
    /// </summary>
    SM_CXSCREEN = 0,

    /// <summary>
    /// The width of a button in a window caption or title bar, in pixels.
    /// </summary>
    SM_CXSIZE = 30,

    /// <summary>
    /// The thickness of the sizing border around the perimeter of a window that can be resized, in pixels. 
    /// SM_CXSIZEFRAME is the width of the horizontal border, and SM_CYSIZEFRAME is the height of the vertical border. 
    /// This value is the same as SM_CXFRAME.
    /// </summary>
    SM_CXSIZEFRAME = 32,

    /// <summary>
    /// The recommended width of a small icon, in pixels. Small icons typically appear in window captions and in small icon view.
    /// </summary>
    SM_CXSMICON = 49,

    /// <summary>
    /// The width of small caption buttons, in pixels.
    /// </summary>
    SM_CXSMSIZE = 52,

    /// <summary>
    /// The width of the virtual screen, in pixels. The virtual screen is the bounding rectangle of all display monitors. 
    /// The SM_XVIRTUALSCREEN metric is the coordinates for the left side of the virtual screen.
    /// </summary>
    SM_CXVIRTUALSCREEN = 78,

    /// <summary>
    /// The width of a vertical scroll bar, in pixels.
    /// </summary>
    SM_CXVSCROLL = 2,

    /// <summary>
    /// The height of a window border, in pixels. This is equivalent to the SM_CYEDGE value for windows with the 3-D look.
    /// </summary>
    SM_CYBORDER = 6,

    /// <summary>
    /// The height of a caption area, in pixels.
    /// </summary>
    SM_CYCAPTION = 4,

    /// <summary>
    /// The height of a cursor, in pixels. The system cannot create cursors of other sizes.
    /// </summary>
    SM_CYCURSOR = 14,

    /// <summary>
    /// This value is the same as SM_CYFIXEDFRAME.
    /// </summary>
    SM_CYDLGFRAME = 8,

    /// <summary>
    /// The height of the rectangle around the location of a first click in a double-click sequence, in pixels. 
    /// The second click must occur within the rectangle defined by SM_CXDOUBLECLK and SM_CYDOUBLECLK for the system to consider 
    /// the two clicks a double-click. The two clicks must also occur within a specified time. To set the height of the double-click 
    /// rectangle, call SystemParametersInfo with SPI_SETDOUBLECLKHEIGHT.
    /// </summary>
    SM_CYDOUBLECLK = 37,

    /// <summary>
    /// The number of pixels above and below a mouse-down point that the mouse pointer can move before a drag operation begins. 
    /// This allows the user to click and release the mouse button easily without unintentionally starting a drag operation. 
    /// If this value is negative, it is subtracted from above the mouse-down point and added below it.
    /// </summary>
    SM_CYDRAG = 69,

    /// <summary>
    /// The height of a 3-D border, in pixels. This is the 3-D counterpart of SM_CYBORDER.
    /// </summary>
    SM_CYEDGE = 46,

    /// <summary>
    /// The thickness of the frame around the perimeter of a window that has a caption but is not sizable, in pixels. 
    /// SM_CXFIXEDFRAME is the height of the horizontal border, and SM_CYFIXEDFRAME is the width of the vertical border. 
    /// This value is the same as SM_CYDLGFRAME.
    /// </summary>
    SM_CYFIXEDFRAME = 8,

    /// <summary>
    /// The height of the top and bottom edges of the focus rectangle drawn byDrawFocusRect. 
    /// This value is in pixels. 
    /// Windows 2000:  This value is not supported.
    /// </summary>
    SM_CYFOCUSBORDER = 84,

    /// <summary>
    /// This value is the same as SM_CYSIZEFRAME.
    /// </summary>
    SM_CYFRAME = 33,

    /// <summary>
    /// The height of the client area for a full-screen window on the primary display monitor, in pixels. 
    /// To get the coordinates of the portion of the screen not obscured by the system taskbar or by application desktop toolbars,
    /// call the SystemParametersInfo function with the SPI_GETWORKAREA value.
    /// </summary>
    SM_CYFULLSCREEN = 17,

    /// <summary>
    /// The height of a horizontal scroll bar, in pixels.
    /// </summary>
    SM_CYHSCROLL = 3,

    /// <summary>
    /// The default height of an icon, in pixels. The LoadIcon function can load only icons with the dimensions SM_CXICON and SM_CYICON.
    /// </summary>
    SM_CYICON = 12,

    /// <summary>
    /// The height of a grid cell for items in large icon view, in pixels. Each item fits into a rectangle of size 
    /// SM_CXICONSPACING by SM_CYICONSPACING when arranged. This value is always greater than or equal to SM_CYICON.
    /// </summary>
    SM_CYICONSPACING = 39,

    /// <summary>
    /// For double byte character set versions of the system, this is the height of the Kanji window at the bottom of the screen, in pixels.
    /// </summary>
    SM_CYKANJIWINDOW = 18,

    /// <summary>
    /// The default height, in pixels, of a maximized top-level window on the primary display monitor.
    /// </summary>
    SM_CYMAXIMIZED = 62,

    /// <summary>
    /// The default maximum height of a window that has a caption and sizing borders, in pixels. This metric refers to the entire desktop. 
    /// The user cannot drag the window frame to a size larger than these dimensions. A window can override this value by processing 
    /// the WM_GETMINMAXINFO message.
    /// </summary>
    SM_CYMAXTRACK = 60,

    /// <summary>
    /// The height of a single-line menu bar, in pixels.
    /// </summary>
    SM_CYMENU = 15,

    /// <summary>
    /// The height of the default menu check-mark bitmap, in pixels.
    /// </summary>
    SM_CYMENUCHECK = 72,

    /// <summary>
    /// The height of menu bar buttons, such as the child window close button that is used in the multiple document interface, in pixels.
    /// </summary>
    SM_CYMENUSIZE = 55,

    /// <summary>
    /// The minimum height of a window, in pixels.
    /// </summary>
    SM_CYMIN = 29,

    /// <summary>
    /// The height of a minimized window, in pixels.
    /// </summary>
    SM_CYMINIMIZED = 58,

    /// <summary>
    /// The height of a grid cell for a minimized window, in pixels. Each minimized window fits into a rectangle this size when arranged. 
    /// This value is always greater than or equal to SM_CYMINIMIZED.
    /// </summary>
    SM_CYMINSPACING = 48,

    /// <summary>
    /// The minimum tracking height of a window, in pixels. The user cannot drag the window frame to a size smaller than these dimensions. 
    /// A window can override this value by processing the WM_GETMINMAXINFO message.
    /// </summary>
    SM_CYMINTRACK = 35,

    /// <summary>
    /// The height of the screen of the primary display monitor, in pixels. This is the same value obtained by calling 
    /// GetDeviceCaps as follows: GetDeviceCaps( hdcPrimaryMonitor, VERTRES).
    /// </summary>
    SM_CYSCREEN = 1,

    /// <summary>
    /// The height of a button in a window caption or title bar, in pixels.
    /// </summary>
    SM_CYSIZE = 31,

    /// <summary>
    /// The thickness of the sizing border around the perimeter of a window that can be resized, in pixels. 
    /// SM_CXSIZEFRAME is the width of the horizontal border, and SM_CYSIZEFRAME is the height of the vertical border. 
    /// This value is the same as SM_CYFRAME.
    /// </summary>
    SM_CYSIZEFRAME = 33,

    /// <summary>
    /// The height of a small caption, in pixels.
    /// </summary>
    SM_CYSMCAPTION = 51,

    /// <summary>
    /// The recommended height of a small icon, in pixels. Small icons typically appear in window captions and in small icon view.
    /// </summary>
    SM_CYSMICON = 50,

    /// <summary>
    /// The height of small caption buttons, in pixels.
    /// </summary>
    SM_CYSMSIZE = 53,

    /// <summary>
    /// The height of the virtual screen, in pixels. The virtual screen is the bounding rectangle of all display monitors. 
    /// The SM_YVIRTUALSCREEN metric is the coordinates for the top of the virtual screen.
    /// </summary>
    SM_CYVIRTUALSCREEN = 79,

    /// <summary>
    /// The height of the arrow bitmap on a vertical scroll bar, in pixels.
    /// </summary>
    SM_CYVSCROLL = 20,

    /// <summary>
    /// The height of the thumb box in a vertical scroll bar, in pixels.
    /// </summary>
    SM_CYVTHUMB = 9,

    /// <summary>
    /// Nonzero if User32.dll supports DBCS; otherwise, 0.
    /// </summary>
    SM_DBCSENABLED = 42,

    /// <summary>
    /// Nonzero if the debug version of User.exe is installed; otherwise, 0.
    /// </summary>
    SM_DEBUG = 22,

    /// <summary>
    /// Nonzero if the current operating system is Windows 7 or Windows Server 2008 R2 and the Tablet PC Input 
    /// service is started; otherwise, 0. The return value is a bitmask that specifies the type of digitizer input supported by the device. 
    /// For more information, see Remarks. 
    /// Windows Server 2008, Windows Vista, and Windows XP/2000:  This value is not supported.
    /// </summary>
    SM_DIGITIZER = 94,

    /// <summary>
    /// Nonzero if Input Method Manager/Input Method Editor features are enabled; otherwise, 0. 
    /// SM_IMMENABLED indicates whether the system is ready to use a Unicode-based IME on a Unicode application. 
    /// To ensure that a language-dependent IME works, check SM_DBCSENABLED and the system ANSI code page.
    /// Otherwise the ANSI-to-Unicode conversion may not be performed correctly, or some components like fonts
    /// or registry settings may not be present.
    /// </summary>
    SM_IMMENABLED = 82,

    /// <summary>
    /// Nonzero if there are digitizers in the system; otherwise, 0. SM_MAXIMUMTOUCHES returns the aggregate maximum of the 
    /// maximum number of contacts supported by every digitizer in the system. If the system has only single-touch digitizers, 
    /// the return value is 1. If the system has multi-touch digitizers, the return value is the number of simultaneous contacts 
    /// the hardware can provide. Windows Server 2008, Windows Vista, and Windows XP/2000:  This value is not supported.
    /// </summary>
    SM_MAXIMUMTOUCHES = 95,

    /// <summary>
    /// Nonzero if the current operating system is the Windows XP, Media Center Edition, 0 if not.
    /// </summary>
    SM_MEDIACENTER = 87,

    /// <summary>
    /// Nonzero if drop-down menus are right-aligned with the corresponding menu-bar item; 0 if the menus are left-aligned.
    /// </summary>
    SM_MENUDROPALIGNMENT = 40,

    /// <summary>
    /// Nonzero if the system is enabled for Hebrew and Arabic languages, 0 if not.
    /// </summary>
    SM_MIDEASTENABLED = 74,

    /// <summary>
    /// Nonzero if a mouse is installed; otherwise, 0. This value is rarely zero, because of support for virtual mice and because 
    /// some systems detect the presence of the port instead of the presence of a mouse.
    /// </summary>
    SM_MOUSEPRESENT = 19,

    /// <summary>
    /// Nonzero if a mouse with a horizontal scroll wheel is installed; otherwise 0.
    /// </summary>
    SM_MOUSEHORIZONTALWHEELPRESENT = 91,

    /// <summary>
    /// Nonzero if a mouse with a vertical scroll wheel is installed; otherwise 0.
    /// </summary>
    SM_MOUSEWHEELPRESENT = 75,

    /// <summary>
    /// The least significant bit is set if a network is present; otherwise, it is cleared. The other bits are reserved for future use.
    /// </summary>
    SM_NETWORK = 63,

    /// <summary>
    /// Nonzero if the Microsoft Windows for Pen computing extensions are installed; zero otherwise.
    /// </summary>
    SM_PENWINDOWS = 41,

    /// <summary>
    /// This system metric is used in a Terminal Services environment to determine if the current Terminal Server session is 
    /// being remotely controlled. Its value is nonzero if the current session is remotely controlled; otherwise, 0. 
    /// You can use terminal services management tools such as Terminal Services Manager (tsadmin.msc) and shadow.exe to 
    /// control a remote session. When a session is being remotely controlled, another user can view the contents of that session 
    /// and potentially interact with it.
    /// </summary>
    SM_REMOTECONTROL = 0x2001,

    /// <summary>
    /// This system metric is used in a Terminal Services environment. If the calling process is associated with a Terminal Services 
    /// client session, the return value is nonzero. If the calling process is associated with the Terminal Services console session, 
    /// the return value is 0. 
    /// Windows Server 2003 and Windows XP:  The console session is not necessarily the physical console. 
    /// For more information, seeWTSGetActiveConsoleSessionId.
    /// </summary>
    SM_REMOTESESSION = 0x1000,

    /// <summary>
    /// Nonzero if all the display monitors have the same color format, otherwise, 0. Two displays can have the same bit depth, 
    /// but different color formats. For example, the red, green, and blue pixels can be encoded with different numbers of bits, 
    /// or those bits can be located in different places in a pixel color value.
    /// </summary>
    SM_SAMEDISPLAYFORMAT = 81,

    /// <summary>
    /// This system metric should be ignored; it always returns 0.
    /// </summary>
    SM_SECURE = 44,

    /// <summary>
    /// The build number if the system is Windows Server 2003 R2; otherwise, 0.
    /// </summary>
    SM_SERVERR2 = 89,

    /// <summary>
    /// Nonzero if the user requires an application to present information visually in situations where it would otherwise present 
    /// the information only in audible form; otherwise, 0.
    /// </summary>
    SM_SHOWSOUNDS = 70,

    /// <summary>
    /// Nonzero if the current session is shutting down; otherwise, 0. Windows 2000:  This value is not supported.
    /// </summary>
    SM_SHUTTINGDOWN = 0x2000,

    /// <summary>
    /// Nonzero if the computer has a low-end (slow) processor; otherwise, 0.
    /// </summary>
    SM_SLOWMACHINE = 73,

    /// <summary>
    /// Nonzero if the current operating system is Windows 7 Starter Edition, Windows Vista Starter, or Windows XP Starter Edition; otherwise, 0.
    /// </summary>
    SM_STARTER = 88,

    /// <summary>
    /// Nonzero if the meanings of the left and right mouse buttons are swapped; otherwise, 0.
    /// </summary>
    SM_SWAPBUTTON = 23,

    /// <summary>
    /// Nonzero if the current operating system is the Windows XP Tablet PC edition or if the current operating system is Windows Vista
    /// or Windows 7 and the Tablet PC Input service is started; otherwise, 0. The SM_DIGITIZER setting indicates the type of digitizer 
    /// input supported by a device running Windows 7 or Windows Server 2008 R2. For more information, see Remarks.
    /// </summary>
    SM_TABLETPC = 86,

    /// <summary>
    /// The coordinates for the left side of the virtual screen. The virtual screen is the bounding rectangle of all display monitors. 
    /// The SM_CXVIRTUALSCREEN metric is the width of the virtual screen.
    /// </summary>
    SM_XVIRTUALSCREEN = 76,

    /// <summary>
    /// The coordinates for the top of the virtual screen. The virtual screen is the bounding rectangle of all display monitors. 
    /// The SM_CYVIRTUALSCREEN metric is the height of the virtual screen.
    /// </summary>
    SM_YVIRTUALSCREEN = 77,
}


[StructLayout(LayoutKind.Sequential)]
public struct COLORREF
{
    public uint ColorDWORD;

    public COLORREF(System.Drawing.Color color)
    {
        ColorDWORD = (uint)color.R + (((uint)color.G) << 8) + (((uint)color.B) << 16);
    }

    public System.Drawing.Color GetColor()
    {
        return System.Drawing.Color.FromArgb((int)(0x000000FFU & ColorDWORD),
         (int)(0x0000FF00U & ColorDWORD) >> 8, (int)(0x00FF0000U & ColorDWORD) >> 16);
    }

    public void SetColor(System.Drawing.Color color)
    {
        ColorDWORD = (uint)color.R + (((uint)color.G) << 8) + (((uint)color.B) << 16);
    }
}
[Flags()]
internal enum DCX
{
    CACHE = 0x2,
    CLIPCHILDREN = 0x8,
    CLIPSIBLINGS = 0x10,
    EXCLUDERGN = 0x40,
    EXCLUDEUPDATE = 0x100,
    INTERSECTRGN = 0x80,
    INTERSECTUPDATE = 0x200,
    LOCKWINDOWUPDATE = 0x400,
    NORECOMPUTE = 0x100000,
    NORESETATTRS = 0x4,
    PARENTCLIP = 0x20,
    VALIDATE = 0x200000,
    WINDOW = 0x1,
}

[Flags]
public enum RedrawWindowFlags
{
    RDW_INVALIDATE = 0x0001,
    RDW_INTERNALPAINT = 0x0002,
    RDW_ERASE = 0x0004,
    RDW_VALIDATE = 0x0008,
    RDW_NOINTERNALPAINT = 0x0010,
    RDW_NOERASE = 0x0020,
    RDW_NOCHILDREN = 0x0040,
    RDW_ALLCHILDREN = 0x0080,
    RDW_UPDATENOW = 0x0100,
    RDW_ERASENOW = 0x0200,
    RDW_FRAME = 0x0400,
    RDW_NOFRAME = 0x0800,

}
public enum SetWindowPosFlags
{
    SWP_NOSIZE = 0x0001,
    SWP_NOMOVE = 0x0002,
    SWP_NOZORDER = 0x0004,
    SWP_NOREDRAW = 0x0008,
    SWP_NOACTIVATE = 0x0010,
    SWP_FRAMECHANGED = 0x0020,
    SWP_SHOWWINDOW = 0x0040,
    SWP_HIDEWINDOW = 0x0080,
    SWP_NOCOPYBITS = 0x0100,
    SWP_NOOWNERZORDER = 0x0200,
    SWP_NOSENDCHANGING = 0x0400,
    SWP_DRAWFRAME = 0x0020,
    SWP_NOREPOSITION = 0x0200,
    SWP_DEFERERASE = 0x2000,
    SWP_ASYNCWINDOWPOS = 0x4000
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BLENDFUNCTION
{
    /// <summary>
    /// BlendOp field of structure
    /// </summary>
    public byte BlendOp;

    /// <summary>
    /// BlendFlags field of structure
    /// </summary>
    public byte BlendFlags;

    /// <summary>
    /// SourceConstantAlpha field of structure
    /// </summary>
    public byte SourceConstantAlpha;

    /// <summary>
    /// AlphaFormat field of structure
    /// </summary>
    public byte AlphaFormat;
}

[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
    /// <summary>
    /// x field of structure
    /// </summary>
    public int x;

    /// <summary>
    /// y field of structure
    /// </summary>
    public int y;

    #region Constructors
    public POINT(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public POINT(Point point)
    {
        x = point.X;
        y = point.Y;
    }

    public override string ToString()
    {
        return $"x:{x} y:{y}";
    }
    #endregion
}

[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPOS
{
    public IntPtr hwnd;
    public IntPtr hwndAfter;
    public int x;
    public int y;
    public int cx;
    public int cy;
    public uint flags;

    #region Overrides
    public override string ToString()
    {
        return x + ":" + y + ":" + cx + ":" + cy + ":" + ((SetWindowPosFlags)flags);
    }
    #endregion
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WNDCLASS
{
    public uint style;
    public IntPtr lpfnWndProc;
    public int cbClsExtra;
    public int cbWndExtra;
    public IntPtr hInstance;
    public IntPtr hIcon;
    public IntPtr hCursor;
    public IntPtr hbrBackground;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string lpszMenuName;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string lpszClassName;
}

[Flags]
public enum WindowExStyles
{
    /// <summary>
    /// Specified WS_EX_DLGMODALFRAME enumeration value.
    /// </summary>
    WS_EX_DLGMODALFRAME = 0x00000001,

    /// <summary>
    /// Specified WS_EX_NOPARENTNOTIFY enumeration value.
    /// </summary>
    WS_EX_NOPARENTNOTIFY = 0x00000004,
    /// <summary>
    /// Specified WS_EX_NOACTIVATE enumeration value.
    /// </summary>
    WS_EX_NOACTIVATE = 0x08000000,
    /// <summary>
    /// Specified WS_EX_TOPMOST enumeration value.
    /// </summary>
    WS_EX_TOPMOST = 0x00000008,

    /// <summary>
    /// Specified WS_EX_ACCEPTFILES enumeration value.
    /// </summary>
    WS_EX_ACCEPTFILES = 0x00000010,

    /// <summary>
    /// Specified WS_EX_TRANSPARENT enumeration value.
    /// </summary>
    WS_EX_TRANSPARENT = 0x00000020,

    /// <summary>
    /// Specified WS_EX_MDICHILD enumeration value.
    /// </summary>
    WS_EX_MDICHILD = 0x00000040,

    /// <summary>
    /// Specified WS_EX_TOOLWINDOW enumeration value.
    /// </summary>
    WS_EX_TOOLWINDOW = 0x00000080,

    /// <summary>
    /// Specified WS_EX_WINDOWEDGE enumeration value.
    /// </summary>
    WS_EX_WINDOWEDGE = 0x00000100,

    /// <summary>
    /// Specified WS_EX_CLIENTEDGE enumeration value.
    /// </summary>
    WS_EX_CLIENTEDGE = 0x00000200,

    /// <summary>
    /// Specified WS_EX_CONTEXTHELP enumeration value.
    /// </summary>
    WS_EX_CONTEXTHELP = 0x00000400,

    /// <summary>
    /// Specified WS_EX_RIGHT enumeration value.
    /// </summary>
    WS_EX_RIGHT = 0x00001000,

    /// <summary>
    /// Specified WS_EX_LEFT enumeration value.
    /// </summary>
    WS_EX_LEFT = 0x00000000,

    /// <summary>
    /// Specified WS_EX_RTLREADING enumeration value.
    /// </summary>
    WS_EX_RTLREADING = 0x00002000,

    /// <summary>
    /// Specified WS_EX_LTRREADING enumeration value.
    /// </summary>
    WS_EX_LTRREADING = 0x00000000,

    /// <summary>
    /// Specified WS_EX_LEFTSCROLLBAR enumeration value.
    /// </summary>
    WS_EX_LEFTSCROLLBAR = 0x00004000,

    /// <summary>
    /// Specified WS_EX_RIGHTSCROLLBAR enumeration value.
    /// </summary>
    WS_EX_RIGHTSCROLLBAR = 0x00000000,

    /// <summary>
    /// Specified WS_EX_CONTROLPARENT enumeration value.
    /// </summary>
    WS_EX_CONTROLPARENT = 0x00010000,

    /// <summary>
    /// Specified WS_EX_STATICEDGE enumeration value.
    /// </summary>
    WS_EX_STATICEDGE = 0x00020000,

    /// <summary>
    /// Specified WS_EX_APPWINDOW enumeration value.
    /// </summary>
    WS_EX_APPWINDOW = 0x00040000,

    /// <summary>
    /// Specified WS_EX_OVERLAPPEDWINDOW enumeration value.
    /// </summary>
    WS_EX_OVERLAPPEDWINDOW = 0x00000300,

    /// <summary>
    /// Specified WS_EX_PALETTEWINDOW enumeration value.
    /// </summary>
    WS_EX_PALETTEWINDOW = 0x00000188,

    /// <summary>
    /// Specified WS_EX_LAYERED enumeration value.
    /// </summary>
    WS_EX_LAYERED = 0x00080000
}

[Flags]
public enum WindowStyles : long
{
    WS_OVERLAPPED = 0x00000000,
    WS_POPUP = 0x80000000,
    WS_CHILD = 0x40000000,
    WS_MINIMIZE = 0x20000000,
    WS_VISIBLE = 0x10000000,
    WS_DISABLED = 0x08000000,
    WS_CLIPSIBLINGS = 0x04000000,
    WS_CLIPCHILDREN = 0x02000000,
    WS_MAXIMIZE = 0x01000000,
    WS_CAPTION = 0x00C00000,
    WS_BORDER = 0x00800000,
    WS_DLGFRAME = 0x00400000,
    WS_VSCROLL = 0x00200000,
    WS_HSCROLL = 0x00100000,
    WS_SYSMENU = 0x00080000,
    WS_THICKFRAME = 0x00040000,
    WS_GROUP = 0x00020000,
    WS_TABSTOP = 0x00010000,
    WS_MINIMIZEBOX = 0x00020000,
    WS_MAXIMIZEBOX = 0x00010000,
    WS_TILED = 0x00000000,
    WS_ICONIC = 0x20000000,
    WS_SIZEBOX = 0x00040000,
    WS_POPUPWINDOW = 0x80880000,
    WS_OVERLAPPEDWINDOW = 0x00CF0000,
    WS_TILEDWINDOW = 0x00CF0000,
    WS_CHILDWINDOW = 0x40000000
}

public enum WindowLongFlags
{
    /// <summary>
    /// Specified GWL_WNDPROC enumeration value.
    /// </summary>
    GWL_WNDPROC = -4,

    /// <summary>
    /// Specified GWL_HINSTANCE enumeration value.
    /// </summary>
    GWL_HINSTANCE = -6,

    /// <summary>
    /// Specified GWL_HWNDPARENT enumeration value.
    /// </summary>
    GWL_HWNDPARENT = -8,

    /// <summary>
    /// Specified GWL_STYLE enumeration value.
    /// </summary>
    GWL_STYLE = -16,

    /// <summary>
    /// Specified GWL_EXSTYLE enumeration value.
    /// </summary>
    GWL_EXSTYLE = -20,

    /// <summary>
    /// Specified GWL_USERDATA enumeration value.
    /// </summary>
    GWL_USERDATA = -21,

    /// <summary>
    /// Specified GWL_ID enumeration value.
    /// </summary>
    GWL_ID = -12
}


[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    /// <summary>
    /// left field of structure
    /// </summary>
    public int left;

    /// <summary>
    /// top field of structure
    /// </summary>
    public int top;

    /// <summary>
    /// right field of structure
    /// </summary>
    public int right;

    /// <summary>
    /// bottom field of structure
    /// </summary>
    public int bottom;

    public int Left
    {
        get => left;
        set => left = value;
    }

    public int Right
    {
        get => right;
        set => right = value;
    }
    public int Top
    {
        get => top;
        set => top = value;
    }
    public int Bottom
    {
        get => bottom;
        set => bottom = value;
    }
    public RECT(int left, int top, int width, int height)
    {
        this.left = left;
        this.top = top;
        right = this.left + width;
        bottom = this.top + height;
    }

    public RECT(Rectangle r)
    {
        left = r.Left;
        top = r.Top;
        right = r.Right;
        bottom = r.Bottom;
    }

    public Rectangle ToRectangle()
    {
        return Rectangle.FromLTRB(Left, Top, Right, Bottom);
    }
    public void Inflate(int width, int height)
    {
        Left -= width;
        Top -= height;
        Right += width;
        Bottom += height;
    }

    #region Properties

    public POINT Location
    {
        get
        {
            return new POINT(left, top);
        }
        set
        {
            right -= (left - value.x);
            bottom -= (bottom - value.y);
            left = value.x;
            top = value.y;
        }
    }

    public int Width
    {
        get { return Math.Abs(right - left); }
        set { right = left + (int)value; }
    }

    public int Height
    {
        get { return Math.Abs(bottom - top); }
        set { bottom = top + (int)value; }
    }
    #endregion

    #region Overrides

    public override string ToString()
    {
        return string.Format("x:{0},y:{1},width:{2},height:{3}", Left, Top, Right - Left, Bottom - Top);
    }

    #endregion

    public static explicit operator Rectangle(RECT rect)
    {
        return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
    }
}

[StructLayout(LayoutKind.Sequential)]
public struct SIZE
{
    /// <summary>
    /// cx field of structure
    /// </summary>
    public int cx;

    /// <summary>
    /// cy field of structure
    /// </summary>
    public int cy;

    public SIZE(Int32 cx, Int32 cy)
    {
        this.cx = cx;
        this.cy = cy;
    }
}

[StructLayout(LayoutKind.Sequential)]
public struct MINMAXINFO
{
    public POINT ptReserved;
    public POINT ptMaxSize;
    public POINT ptMaxPosition;
    public POINT ptMinTrackSize;
    public POINT ptMaxTrackSize;
}

public enum HitTest : int
{
    HTERROR = (-2),
    HTTRANSPARENT = (-1),
    HTNOWHERE = 0,
    HTCLIENT = 1,
    HTCAPTION = 2,
    HTSYSMENU = 3,
    HTGROWBOX = 4,
    HTSIZE = HTGROWBOX,
    HTMENU = 5,
    HTHSCROLL = 6,
    HTVSCROLL = 7,
    HTMINBUTTON = 8,
    HTMAXBUTTON = 9,
    HTLEFT = 10,
    HTRIGHT = 11,
    HTTOP = 12,
    HTTOPLEFT = 13,
    HTTOPRIGHT = 14,
    HTBOTTOM = 15,
    HTBOTTOMLEFT = 16,
    HTBOTTOMRIGHT = 17,
    HTBORDER = 18,
    HTREDUCE = HTMINBUTTON,
    HTZOOM = HTMAXBUTTON,
    HTSIZEFIRST = HTLEFT,
    HTSIZELAST = HTBOTTOMRIGHT,
    HTOBJECT = 19,
    HTCLOSE = 20,
    HTHELP = 21
}

public enum IdcStandardCursors
{
    IDC_ARROW = 32512,
    IDC_IBEAM = 32513,
    IDC_WAIT = 32514,
    IDC_CROSS = 32515,
    IDC_UPARROW = 32516,
    IDC_SIZE = 32640,
    IDC_ICON = 32641,
    IDC_SIZENWSE = 32642,
    IDC_SIZENESW = 32643,
    IDC_SIZEWE = 32644,
    IDC_SIZENS = 32645,
    IDC_SIZEALL = 32646,
    IDC_NO = 32648,
    IDC_HAND = 32649,
    IDC_APPSTARTING = 32650,
    IDC_HELP = 32651
}

public enum ShowWindowStyles : uint
{
    /// <summary>
    /// Specified SW_HIDE enumeration value.
    /// </summary>
    SW_HIDE = 0,

    /// <summary>
    /// Specified SW_SHOWNORMAL enumeration value.
    /// </summary>
    SW_SHOWNORMAL = 1,

    /// <summary>
    /// Specified SW_NORMAL enumeration value.
    /// </summary>
    SW_NORMAL = 1,

    /// <summary>
    /// Specified SW_SHOWMINIMIZED enumeration value.
    /// </summary>
    SW_SHOWMINIMIZED = 2,

    /// <summary>
    /// Specified SW_SHOWMAXIMIZED enumeration value.
    /// </summary>
    SW_SHOWMAXIMIZED = 3,

    /// <summary>
    /// Specified SW_MAXIMIZE enumeration value.
    /// </summary>
    SW_MAXIMIZE = 3,

    /// <summary>
    /// Specified SW_SHOWNOACTIVATE enumeration value.
    /// </summary>
    SW_SHOWNOACTIVATE = 4,

    /// <summary>
    /// Specified SW_SHOW enumeration value.
    /// </summary>
    SW_SHOW = 5,

    /// <summary>
    /// Specified SW_MINIMIZE enumeration value.
    /// </summary>
    SW_MINIMIZE = 6,

    /// <summary>
    /// Specified SW_SHOWMINNOACTIVE enumeration value.
    /// </summary>
    SW_SHOWMINNOACTIVE = 7,

    /// <summary>
    /// Specified SW_SHOWNA enumeration value.
    /// </summary>
    SW_SHOWNA = 8,

    /// <summary>
    /// Specified SW_RESTORE enumeration value.
    /// </summary>
    SW_RESTORE = 9,

    /// <summary>
    /// Specified SW_SHOWDEFAULT enumeration value.
    /// </summary>
    SW_SHOWDEFAULT = 10,

    /// <summary>
    /// Specified SW_FORCEMINIMIZE enumeration value.
    /// </summary>
    SW_FORCEMINIMIZE = 11,

    /// <summary>
    /// Specified SW_MAX enumeration value.
    /// </summary>
    SW_MAX = 11
}

public enum ResizeDirection
{
    Left = 61441,
    Right = 61442,
    Top = 61443,
    TopLeft = 61444,
    TopRight = 61445,
    Bottom = 61446,
    BottomLeft = 61447,
    BottomRight = 61448,
}

[Flags]
public enum WindowSizeEdges : uint
{
    WMSZ_LEFT = 1,
    WMSZ_RIGHT = 2,
    WMSZ_TOP = 3,
    WMSZ_TOPLEFT = 4,
    WMSZ_TOPRIGHT = 5,
    WMSZ_BOTTOM = 6,
    WMSZ_BOTTOMLEFT = 7,
    WMSZ_BOTTOMRIGHT = 8
}

//[StructLayout(LayoutKind.Sequential)]
//public struct NCCALCSIZE_PARAMS
//{
//	public RECT rect0;
//	public RECT rect1;
//	public RECT rect2;
//	// Can't use an array here so simulate one
//	public IntPtr lppos;
//}

[StructLayout(LayoutKind.Sequential)]
public struct NCCALCSIZE_PARAMS
{
    /// <summary>
    /// Contains the new coordinates of a window that has been moved or resized, that is, it is the proposed new window coordinates.
    /// </summary>
    public RECT rectProposed;
    /// <summary>
    /// Contains the coordinates of the window before it was moved or resized.
    /// </summary>
    public RECT rectBeforeMove;
    /// <summary>
    /// Contains the coordinates of the window's client area before the window was moved or resized.
    /// </summary>
    public RECT rectClientBeforeMove;
    /// <summary>
    /// Pointer to a WINDOWPOS structure that contains the size and position values specified in the operation that moved or resized the window.
    /// </summary>
    public IntPtr lppos;
}

public enum WindowSizeMessageFlags : int
{
    SIZE_RESTORED = 0,
    SIZE_MINIMIZED = 1,
    SIZE_MAXIMIZED = 2,
    SIZE_MAXSHOW = 3,
    SIZE_MAXHIDE = 4
}

public enum AppBarMessageFlags : uint
{
    ABS_AUTOHIDE = 0x1,
    ABM_GETSTATE = 0x4,
}

public enum DeviceCap
{
    /// <summary>
    /// Device driver version
    /// </summary>
    DRIVERVERSION = 0,
    /// <summary>
    /// Device classification
    /// </summary>
    TECHNOLOGY = 2,
    /// <summary>
    /// Horizontal size in millimeters
    /// </summary>
    HORZSIZE = 4,
    /// <summary>
    /// Vertical size in millimeters
    /// </summary>
    VERTSIZE = 6,
    /// <summary>
    /// Horizontal width in pixels
    /// </summary>
    HORZRES = 8,
    /// <summary>
    /// Vertical height in pixels
    /// </summary>
    VERTRES = 10,
    /// <summary>
    /// Number of bits per pixel
    /// </summary>
    BITSPIXEL = 12,
    /// <summary>
    /// Number of planes
    /// </summary>
    PLANES = 14,
    /// <summary>
    /// Number of brushes the device has
    /// </summary>
    NUMBRUSHES = 16,
    /// <summary>
    /// Number of pens the device has
    /// </summary>
    NUMPENS = 18,
    /// <summary>
    /// Number of markers the device has
    /// </summary>
    NUMMARKERS = 20,
    /// <summary>
    /// Number of fonts the device has
    /// </summary>
    NUMFONTS = 22,
    /// <summary>
    /// Number of colors the device supports
    /// </summary>
    NUMCOLORS = 24,
    /// <summary>
    /// Size required for device descriptor
    /// </summary>
    PDEVICESIZE = 26,
    /// <summary>
    /// Curve capabilities
    /// </summary>
    CURVECAPS = 28,
    /// <summary>
    /// Line capabilities
    /// </summary>
    LINECAPS = 30,
    /// <summary>
    /// Polygonal capabilities
    /// </summary>
    POLYGONALCAPS = 32,
    /// <summary>
    /// Text capabilities
    /// </summary>
    TEXTCAPS = 34,
    /// <summary>
    /// Clipping capabilities
    /// </summary>
    CLIPCAPS = 36,
    /// <summary>
    /// Bitblt capabilities
    /// </summary>
    RASTERCAPS = 38,
    /// <summary>
    /// Length of the X leg
    /// </summary>
    ASPECTX = 40,
    /// <summary>
    /// Length of the Y leg
    /// </summary>
    ASPECTY = 42,
    /// <summary>
    /// Length of the hypotenuse
    /// </summary>
    ASPECTXY = 44,
    /// <summary>
    /// Shading and Blending caps
    /// </summary>
    SHADEBLENDCAPS = 45,

    /// <summary>
    /// Logical pixels inch in X
    /// </summary>
    LOGPIXELSX = 88,
    /// <summary>
    /// Logical pixels inch in Y
    /// </summary>
    LOGPIXELSY = 90,

    /// <summary>
    /// Number of entries in physical palette
    /// </summary>
    SIZEPALETTE = 104,
    /// <summary>
    /// Number of reserved entries in palette
    /// </summary>
    NUMRESERVED = 106,
    /// <summary>
    /// Actual color resolution
    /// </summary>
    COLORRES = 108,

    // Printing related DeviceCaps. These replace the appropriate Escapes
    /// <summary>
    /// Physical Width in device units
    /// </summary>
    PHYSICALWIDTH = 110,
    /// <summary>
    /// Physical Height in device units
    /// </summary>
    PHYSICALHEIGHT = 111,
    /// <summary>
    /// Physical Printable Area x margin
    /// </summary>
    PHYSICALOFFSETX = 112,
    /// <summary>
    /// Physical Printable Area y margin
    /// </summary>
    PHYSICALOFFSETY = 113,
    /// <summary>
    /// Scaling factor x
    /// </summary>
    SCALINGFACTORX = 114,
    /// <summary>
    /// Scaling factor y
    /// </summary>
    SCALINGFACTORY = 115,

    /// <summary>
    /// Current vertical refresh rate of the display device (for displays only) in Hz
    /// </summary>
    VREFRESH = 116,
    /// <summary>
    /// Vertical height of entire desktop in pixels
    /// </summary>
    DESKTOPVERTRES = 117,
    /// <summary>
    /// Horizontal width of entire desktop in pixels
    /// </summary>
    DESKTOPHORZRES = 118,
    /// <summary>
    /// Preferred blt alignment
    /// </summary>
    BLTALIGNMENT = 119
}

internal enum PROCESS_DPI_AWARENESS
{
    PROCESS_DPI_UNAWARE = 0,
    PROCESS_SYSTEM_DPI_AWARE = 1,
    PROCESS_PER_MONITOR_DPI_AWARE = 2
}

internal enum DpiAwarenessContext
{
    DPI_AWARENESS_CONTEXT_UNSPECIFIED = 0,
    DPI_AWARENESS_CONTEXT_UNAWARE = -1,
    DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = -2,
    DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = -3,
    DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = -4
}

internal enum DpiType
{
    Effective = 0,
    Angular = 1,
    Raw = 2,
}

internal enum MonitorOptions : uint
{
    MONITOR_DEFAULTTONULL = 0x00000000,
    MONITOR_DEFAULTTOPRIMARY = 0x00000001,
    MONITOR_DEFAULTTONEAREST = 0x00000002
}

internal struct WINDOWPLACEMENT
{
    public int length;
    public int flags;
    public uint showCmd;
    public POINT ptMinPosition;
    public POINT ptMaxPosition;
    public RECT rcNormalPosition;
}

internal enum WmSizingParameters
{
    WMSZ_LEFT = 1,
    WMSZ_RIGHT = 2,
    WMSZ_TOP = 3,
    WMSZ_TOPLEFT = 4,
    WMSZ_TOPRIGHT = 5,
    WMSZ_BOTTOM = 6,
    WMSZ_BOTTOMLEFT = 7,
    WMSZ_BOTTOMRIGHT = 8
}
internal enum TernaryRasterOperations : uint
{
    SRCCOPY = 0x00CC0020,
    SRCPAINT = 0x00EE0086,
    SRCAND = 0x008800C6,
    SRCINVERT = 0x00660046,
    SRCERASE = 0x00440328,
    NOTSRCCOPY = 0x00330008,
    NOTSRCERASE = 0x001100A6,
    MERGECOPY = 0x00C000CA,
    MERGEPAINT = 0x00BB0226,
    PATCOPY = 0x00F00021,
    PATPAINT = 0x00FB0A09,
    PATINVERT = 0x005A0049,
    DSTINVERT = 0x00550009,
    BLACKNESS = 0x00000042,
    WHITENESS = 0x00FF0062,
    CAPTUREBLT = 0x40000000 //only if WinVer >= 5.0.0 (see wingdi.h)
}


internal enum BlendFlags : uint
{
    None = 0x00,
    ULW_COLORKEY = 0x01,
    ULW_ALPHA = 0x02,
    ULW_OPAQUE = 0x04
}



[StructLayout(LayoutKind.Sequential)]
internal unsafe struct UPDATELAYEREDWINDOWINFO
{
    public static readonly int Size = Marshal.SizeOf(typeof(UPDATELAYEREDWINDOWINFO));
    public int cbSize;
    public IntPtr hdcDst;
    public POINT* pptDst;
    public SIZE* psize;
    public IntPtr hdcSrc;
    public POINT* pptSrc;
    public int crKey;
    //BLENDFUNCTION is the same as in the first part of the question
    public BLENDFUNCTION* pblend;
    //BlendFlags is the same as in the first part of the question
    public BlendFlags dwFlags;
    public RECT* prcDirty;
}